﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Dude.Data.Meta;
using Dude.MLS;
using System.IO;
using Dude.Extensions;
using System.Reflection;
using System.Data.Common;

namespace Dude.GUI.ModelEdit
{
    public partial class ModelEditForm : Form
    {
        private DataModel dataModel;
        public DataModel DataModel {
            get
            {
                return dataModel;
            }
            set
            {
                dataModel = value;
                propertyGrid1.SelectedObject = DataModel;
                RefreshModelTreeView();
            }
        }

        public ModelEditForm()
        {
            InitializeComponent();

            Lang.LocalizeUI(this);

            DataModel = new DataModel();

//            DatabaseInfo db = new DatabaseInfo();

            propertyGrid1.SelectedObject = DataModel;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //if (label1.DataBindings.Count > 0) label1.DataBindings.Clear();
            //label1.DataBindings.Add("Text", model.DisplayName, "Text");

            RefreshModelTreeView();
        }

        private void RefreshModelTreeView()
        {
            treeView1.BeginUpdate();
            try
            {
                treeView1.Nodes.Clear();

                TreeNode tn_root = treeView1.Nodes.Add("Connections");
                tn_root.Tag = null;

                foreach (DatabaseConnectionInfo dbci in DataModel.Connections)
                {
                    TreeNode tn_db = tn_root.Nodes.Add(dbci.ToString());
                    tn_db.Tag = dbci;
                }

                tn_root = treeView1.Nodes.Add(DataModel.ToString());
                tn_root.Tag = DataModel;

                foreach (DatabaseInfo db in DataModel.Databases)
                {
                    TreeNode tn_db = tn_root.Nodes.Add(db.ToString());
                    tn_db.Tag = db;
                    foreach (TableInfo table in db.Tables)
                    {
                        TreeNode tn_table = tn_db.Nodes.Add(table.ToString());
                        tn_table.Tag = table;
                        foreach (DataFieldInfo field in table.Fields)
                        {
                            TreeNode tn_field = tn_table.Nodes.Add(field.ToString());
                            tn_field.Tag = field;
                        }
                    }
                }

            }
            finally
            {
                treeView1.EndUpdate();
            }
        }

        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DataModel = new DataModel();
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog openDialog = new OpenFileDialog();
            openDialog.InitialDirectory = AppDomain.CurrentDomain.BaseDirectory;
            openDialog.Multiselect = false;
            openDialog.Title = Lang.GetText("Open Dude Model file");
            openDialog.ValidateNames = true;
            if (openDialog.ShowDialog(this) == DialogResult.OK)
            {
                DataModel = DataModel.Load(openDialog.FileName);
            }
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveDialog = new SaveFileDialog();
            saveDialog.InitialDirectory = AppDomain.CurrentDomain.BaseDirectory;
            saveDialog.OverwritePrompt = false;
            saveDialog.Title = Lang.GetText("Save Dude Model file");
            if (saveDialog.ShowDialog(this) == DialogResult.OK)
            {
                FileInfo fi = new FileInfo(saveDialog.FileName);
                if (fi.AskForBackup(this))
                    DataModel.Save(saveDialog.FileName);
            }
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            propertyGrid1.SelectedObject = e.Node.Tag;
            if (e.Node.Tag is DatabaseConnectionInfo)
            {
                CurrentDBConnectionInfo = (DatabaseConnectionInfo)(e.Node.Tag);
            }
            else
            {
                CurrentDBConnectionInfo = null;
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            dataGridView1.DataSource = System.Data.Common.DbProviderFactories.GetFactoryClasses();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            string AssemblyName = "Npgsql";
            string TypeName = "Npgsql.NpgsqlFactory";

            Dude.Data.Providers.GetDbProviderFactory(TypeName, AssemblyName);

        }

        private DatabaseConnectionInfo currDBConInfo;
        public DatabaseConnectionInfo CurrentDBConnectionInfo
        {
            get
            {
                return currDBConInfo;
            }
            set
            {
                currDBConInfo = value;
                button4.Enabled = (value != null);
            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            Dude.Data.Forms.DatabaseConnectionInfoForm frm = new Dude.Data.Forms.DatabaseConnectionInfoForm();

            frm.DatabaseConnectionInfo = CurrentDBConnectionInfo;
            frm.ShowDialog();
        }

        private void button5_Click(object sender, EventArgs e)
        {
            DbProviderFactory f = CurrentDBConnectionInfo.GetDbProviderFactory();
            using (DbConnection conn = f.CreateConnection())
            {
                conn.ConnectionString = CurrentDBConnectionInfo.ConnectionString;
                conn.Open();

                Dude.Data.Postgres.PostgresMetadataGenerator metagen = new Dude.Data.Postgres.PostgresMetadataGenerator();
                metagen.ProviderFactory = f;
                metagen.Connection = conn;

                StringBuilder sb = new StringBuilder();

                foreach (DataRow tabrow in metagen.GetTablesEnumerator())
                {
                    string tabname = tabrow[0].ToString();
                    foreach (DataRow frow in metagen.GetFieldsEnumerator(tabname))
                    {
                        string fieldname = frow[0].ToString();
                        sb.AppendLine(string.Format("{0}.{1} {2}",tabname,fieldname,frow[1].ToString()));
                    }
                    sb.AppendLine();
                }

                this.textBox1.Text = sb.ToString();
                
                //DbDataAdapter da = f.CreateDataAdapter();

                //da.SelectCommand = cmd;
                
                //DbCommandBuilder b = f.CreateCommandBuilder();
                //b.DataAdapter = da;
                //DbCommand cmd2 = b.GetUpdateCommand(true);
            }
        }

        private void button6_Click(object sender, EventArgs e)
        {
            StringBuilder sb = new StringBuilder();
            StringWriter tw = new StringWriter(sb);
            tw.NewLine = "\n";
            GenericSQLCreateScriptBuider sqlcb = new GenericSQLCreateScriptBuider(tw);
            sqlcb.Process(DataModel);

            this.textBox1.Text = sb.ToString().Replace("\n","\r\n");
        }

    }
}
